package com.imooc.sell.service.impl;

import com.imooc.sell.dao.ProductCategoryDao;
import com.imooc.sell.dataobject.ProductCategory;
import com.imooc.sell.dataobject.query.CategoryQuery;
import com.imooc.sell.enums.SortEnum;
import com.imooc.sell.enums.enumUtils.EnumUtil;
import com.imooc.sell.service.CategoryService;
import lombok.Data;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import static com.imooc.sell.enums.SortEnum.SORT_BYCATEGORY_ASC;
import static com.imooc.sell.enums.SortEnum.SORT_BYID_ASC;
import static com.imooc.sell.enums.SortEnum.SORT_BYTIME_DESC;

/**
 * 类目服务层
 */
@Service
@Data
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private ProductCategoryDao categoryDao;

    @Override
    public ProductCategory getOne(Integer Id) {
        return categoryDao.getOne(Id);
    }

    @Override
    public List<ProductCategory> findAll() {
        return categoryDao.findAll();
    }

    @Override
    public Page<ProductCategory> findAll(Pageable pageable) {
        return categoryDao.findAll(pageable);
    }

    @Override
    public List<ProductCategory> findByCategoryTypeIn(List<Integer> typeList) {
        return categoryDao.findByCategoryTypeIn(typeList);
    }

    @Override
    public ProductCategory save(ProductCategory productCategory) {
        ProductCategory productCategorytmp;
        try {
            if (productCategory.getId() == null) {
                productCategorytmp = categoryDao.save(productCategory);
            } else {
                ProductCategory productCategory1 = categoryDao.getOne(productCategory.getId());
                BeanUtils.copyProperties(productCategory, productCategory1);
                productCategorytmp = categoryDao.save(productCategory1);
            }
        } catch (Exception e) {
            return null;
        }
        return productCategorytmp;
    }

    @Override
    public Boolean deletCategory(Integer id) {
        try {
            categoryDao.deleteById(id);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    @Override
    public void deleteByCategoryTypeIn(List<Integer> idList) {
        try {
            categoryDao.deleteByCategoryTypeIn(idList);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public Page<ProductCategory> findCategoryCrCriteria(Integer page, Integer size, CategoryQuery categoryQuery, Integer sortCode) {
        Page<ProductCategory> categoryPage = categoryDao.findAll(new Specification<ProductCategory>() {
            @Override
            public Predicate toPredicate(Root<ProductCategory> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                if (null != categoryQuery.getId() && !"".equals(categoryQuery.getId())) {
                    list.add(criteriaBuilder.equal(root.get("id").as(String.class), categoryQuery.getId()));
                }
                if (null != categoryQuery.getCategoryType() && !"".equals(categoryQuery.getCategoryType())) {
                    list.add(criteriaBuilder.equal(root.get("categoryType").as(String.class), categoryQuery.getCategoryType()));
                }
                if (null != categoryQuery.getCategoryName() && !"".equals(categoryQuery.getCategoryName())) {
                    list.add(criteriaBuilder.equal(root.get("categoryName").as(String.class), categoryQuery.getCategoryName()));
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, EnumUtil.getPageable(page, size, sortCode));
        return categoryPage;
    }

    @Override
    public Page<ProductCategory> findCategoryByTime(Date createTime, Date endTime, Integer page, Integer size) {
        Pageable pageable = new PageRequest(page, size, Sort.Direction.ASC, "createTime");
        Page<ProductCategory> categoryPage = categoryDao.findAll(new Specification<ProductCategory>() {
            @Nullable
            @Override
            public Predicate toPredicate(Root<ProductCategory> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<Predicate>();
                try {
                    if (createTime != null && endTime != null) {
                        list.add(criteriaBuilder.between(root.get("createTime"),
                                createTime,
                                endTime));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Predicate[] p = new Predicate[list.size()];
                return criteriaBuilder.and(list.toArray(p));
            }
        }, pageable);
        return categoryPage;
    }
}
